﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace BigDataFramework.Library.Objects.Threading
{
    /// <summary>
    /// Provides a template for creating a Thread
    /// </summary>
    public abstract class ThreadBase
    {
        /// <summary>
        /// Mutex for the _isRunningBool. When locked, the _isRunning property is being read or set
        /// </summary>
        private object _mutex_isRunning;
        /// <summary>
        /// Bool which shows if the thread is still running
        /// </summary>
        private bool _isRunning { get; set; }
        /// <summary>
        /// Performs the actual meat and potatoes of the thread class
        /// </summary>
        private void _Run()
        {
            this._Started();
            this.Run();
            this._Completed();
        }
        /// <summary>
        /// Throws off the OnStarted event
        /// </summary>
        private void _Started()
        {
            this.IsRunning = true;

            if (this.OnStarted == null)
                return;

            this.OnStarted(this);
        }
        /// <summary>
        /// Throws off the OnCompleted event
        /// </summary>
        private void _Completed()
        {
            this.IsRunning = false;

            if (this.OnCompleted == null)
                return;

            this.OnCompleted(this);
        }
        /// <summary>
        /// Returns True if the thread is currently running, false otherwise
        /// </summary>
        public bool IsRunning
        {
            get
            {
                lock (this._mutex_isRunning)
                {
                    return this._isRunning;
                }
            }
            private set
            {
                lock (this._mutex_isRunning)
                {
                    this._isRunning = value;
                }
            }
        }
        /// <summary>
        /// Starts the Thread
        /// </summary>
        public void Start()
        {
            this._Run();
        }
        /// <summary>
        /// The action for this thread to perform
        /// </summary>
        public abstract void Run();
        /// <summary>
        /// Subscribe to the event any methods which should be called on thread completion
        /// </summary>
        public event OnCompletedHandler OnCompleted;
        public delegate void OnCompletedHandler(ThreadBase tb);
        /// <summary>
        /// Subscribe to this event any methods which should be called on thread start
        /// </summary>
        public event OnStartedHandler OnStarted;
        public delegate void OnStartedHandler(ThreadBase tb);
    }
}
